package com.autumn.util.data;

import java.util.ArrayList;
import java.util.List;

import com.autumn.common.api.application.dto.input.QueryCriteriaItem;
import com.autumn.common.api.domain.entities.IEntity;
import com.autumn.common.api.domain.entities.auditing.ISoftDelete;
import com.autumn.domain.repositories.IEntityRepository;
import com.autumn.mybatis.criterion.ICriteriaBean;
import com.autumn.mybatis.criterion.LockModeEnum;
import com.autumn.mybatis.criterion.Query;

/**
 * 数据查询帮助
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2017-12-31 03:14:39
 */
public class DbQueryUtils {

	/**
	 * 基于主键查询(如果实现了 ISoftDelete 接口则会自动过滤)
	 * 
	 * @param repository
	 *            仓储
	 * @param entityClass
	 *            实体类型
	 * @param id
	 *            主键
	 * @return
	 */
	public static <TEntity extends IEntity<TPrimaryKey>, TPrimaryKey> TEntity queryById(
			IEntityRepository<TEntity, TPrimaryKey> repository, Class<TEntity> entityClass, TPrimaryKey id) {
		return queryById(repository, entityClass, id, LockModeEnum.NONE);
	}

	/**
	 * 基于主键查询(如果实现了 ISoftDelete 接口则会自动过滤)
	 * 
	 * @param repository
	 *            仓储
	 * @param entityClass
	 *            实体类型
	 * @param id
	 *            主键
	 * @param lockMode
	 *            锁模式
	 * @return
	 */
	public static <TEntity extends IEntity<TPrimaryKey>, TPrimaryKey> TEntity queryById(
			IEntityRepository<TEntity, TPrimaryKey> repository, Class<TEntity> entityClass, TPrimaryKey id,
			LockModeEnum lockMode) {
		if (ISoftDelete.class.isAssignableFrom(entityClass)) {
			Query query = new Query(entityClass);
			query.eq("id", id).eq("isDelete", false);
			if (lockMode != null) {
				query = query.lock(LockModeEnum.UPDATE);
			}
			return repository.selectFirst(query.builderSection());
		} else {
			if (lockMode != null && !lockMode.equals(LockModeEnum.NONE)) {
				return repository.getByLock(id, lockMode);
			}
			return repository.get(id);
		}
	}

	/**
	 * 转换为条件Bean 列表
	 * 
	 * @param criteriaItems
	 *            条件项目列表
	 * @return
	 */
	public static List<ICriteriaBean> toCriteriaBeanList(List<QueryCriteriaItem> criteriaItems) {
		List<ICriteriaBean> items = new ArrayList<>();
		if (criteriaItems != null) {
			for (QueryCriteriaItem item : criteriaItems) {
				ICriteriaBean inputItem = new QueryCriteriaItemInput();
				inputItem.setExpression(item.getExpression());
				inputItem.setLogic(item.getLogic());
				inputItem.setOp(item.getOp());
				inputItem.setValue(item.getValue());
				inputItem.setSecondValue(item.getSecondValue());
				items.add(inputItem);
			}
		}
		return items;
	}

}
